/*
 *  Copyright 2019-2023 oyun
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.oyun.modules.medicine.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.oyun.modules.medicine.domain.ManipulationIllness;
import com.oyun.modules.medicine.domain.ManipulationNillness;
import com.oyun.modules.medicine.domain.TherapeuticManipulation;
import com.oyun.modules.medicine.domain.vo.TherapeuticManipulationQueryCriteria;
import com.oyun.modules.medicine.mapper.ManipulationIllnessMapper;
import com.oyun.modules.medicine.mapper.ManipulationNillnessMapper;
import com.oyun.modules.medicine.mapper.TherapeuticManipulationMapper;
import com.oyun.modules.medicine.service.TherapeuticManipulationService;
import com.oyun.segment.convert.itmd.IntermediateCodeUtils;
import com.oyun.utils.FileUtil;
import com.oyun.utils.PageResult;
import com.oyun.utils.PageUtil;
import com.oyun.utils.StringUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author oyun
 * @description 服务实现
 * @date 2024-05-07
 **/
@Service
@RequiredArgsConstructor
public class TherapeuticManipulationServiceImpl extends ServiceImpl<TherapeuticManipulationMapper, TherapeuticManipulation> implements TherapeuticManipulationService {

    private final TherapeuticManipulationMapper therapeuticManipulationMapper;

    private final ManipulationIllnessMapper manipulationIllnessMapper;//治疗手法适应疾病

    private final ManipulationNillnessMapper manipulationNillnessMapper;//治疗手法禁忌疾病

    @Override
    public PageResult<TherapeuticManipulation> queryAll(TherapeuticManipulationQueryCriteria criteria, Page<Object> page) {
        if (StringUtils.isNotEmpty(criteria.getName())) {
            criteria.setReplaceAll(IntermediateCodeUtils.mn2Code(criteria.getName()).replaceAll("-", " -"));
        }
        IPage<TherapeuticManipulation> all = therapeuticManipulationMapper.findAll(criteria, page);
        acquire(all.getRecords());
        return PageUtil.toPage(all);
    }

    @Override
    public List<TherapeuticManipulation> queryAll(TherapeuticManipulationQueryCriteria criteria) {
        return therapeuticManipulationMapper.findAll(criteria);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(TherapeuticManipulation resources) {
        convertCode(resources);
        save(resources);
        insertOrUpdate(resources);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(TherapeuticManipulation resources) {
        TherapeuticManipulation therapeuticManipulation = getById(resources.getId());
        therapeuticManipulation.copy(resources);
        convertCode(therapeuticManipulation);
        saveOrUpdate(therapeuticManipulation);

        LambdaQueryWrapper<ManipulationIllness> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ManipulationIllness::getTpticMnpltId, resources.getId()).eq(ManipulationIllness::getStatus, 1);
        List<ManipulationIllness> list = manipulationIllnessMapper.selectList(wrapper);
        for (ManipulationIllness manipulationIllness : list) {
            manipulationIllness.setStatus(0);
            manipulationIllnessMapper.updateById(manipulationIllness);
        }
        LambdaQueryWrapper<ManipulationNillness> wrapper1 = new LambdaQueryWrapper<>();
        wrapper1.eq(ManipulationNillness::getTpticMnpltId, resources.getId()).eq(ManipulationNillness::getStatus, 1);
        List<ManipulationNillness> list1 = manipulationNillnessMapper.selectList(wrapper1);
        for (ManipulationNillness manipulationNillness : list1) {
            manipulationNillness.setStatus(0);
            manipulationNillnessMapper.updateById(manipulationNillness);
        }

        insertOrUpdate(resources);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteAll(List<Long> ids) {
        removeBatchByIds(ids);
        LambdaQueryWrapper<ManipulationIllness> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(ManipulationIllness::getTpticMnpltId, ids).eq(ManipulationIllness::getStatus, 1);
        List<ManipulationIllness> list = manipulationIllnessMapper.selectList(wrapper);
        for (ManipulationIllness manipulationIllness : list) {
            manipulationIllness.setStatus(0);
            manipulationIllnessMapper.updateById(manipulationIllness);
        }
        LambdaQueryWrapper<ManipulationNillness> wrapper1 = new LambdaQueryWrapper<>();
        wrapper1.in(ManipulationNillness::getTpticMnpltId, ids).eq(ManipulationNillness::getStatus, 1);
        List<ManipulationNillness> list1 = manipulationNillnessMapper.selectList(wrapper1);
        for (ManipulationNillness manipulationNillness : list1) {
            manipulationNillness.setStatus(0);
            manipulationNillnessMapper.updateById(manipulationNillness);
        }

    }

    @Override
    public void download(List<TherapeuticManipulation> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (TherapeuticManipulation therapeuticManipulation : all) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("治疗技术名称", therapeuticManipulation.getMnName());
            map.put(" mnNameCode", therapeuticManipulation.getMnNameCode());
            map.put(" zhName", therapeuticManipulation.getZhName());
            map.put("蒙语解释", therapeuticManipulation.getMnExplain());
            map.put(" zhExplain", therapeuticManipulation.getZhExplain());
            map.put("蒙语疗法", therapeuticManipulation.getMnTherapy());
            map.put(" zhTherapy", therapeuticManipulation.getZhTherapy());
            map.put(" mnTherapyCode", therapeuticManipulation.getMnTherapyCode());
            map.put(" mnExplainCode", therapeuticManipulation.getMnExplainCode());
            map.put("蒙语注意事项", therapeuticManipulation.getMnAttention());
            map.put(" mnAttentionCode", therapeuticManipulation.getMnAttentionCode());
            map.put(" zhAttention", therapeuticManipulation.getZhAttention());
            map.put("蒙语效用", therapeuticManipulation.getMnUtility());
            map.put(" zhUtility", therapeuticManipulation.getZhUtility());
            map.put(" mnUtilityCode", therapeuticManipulation.getMnUtilityCode());
            map.put(" createBy", therapeuticManipulation.getCreateBy());
            map.put(" createTime", therapeuticManipulation.getCreateTime());
            map.put(" updateBy", therapeuticManipulation.getUpdateBy());
            map.put(" updateTime", therapeuticManipulation.getUpdateTime());
            map.put(" status", therapeuticManipulation.getStatus());
            map.put("备注", therapeuticManipulation.getRemark());
            map.put("分类(字典)", therapeuticManipulation.getType());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    @Override
    public Object getByName(String name) {
        String replaceAll = IntermediateCodeUtils.mn2Code(name).replaceAll("-", " -");
        LambdaQueryWrapper<TherapeuticManipulation> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(TherapeuticManipulation::getZhName, name).or().like(TherapeuticManipulation::getMnNameCode, replaceAll);
        List<TherapeuticManipulation> selectList = therapeuticManipulationMapper.selectList(wrapper);
        acquire(selectList);
        return selectList;
    }

    private void insertOrUpdate(TherapeuticManipulation resources) {
        for (Long illnessId : resources.getIllnessIds()) {
            ManipulationIllness illness = new ManipulationIllness();
            illness.setIllnessId(illnessId);
            illness.setTpticMnpltId(resources.getId());
            illness.setStatus(1);
            manipulationIllnessMapper.insert(illness);
        }
        for (Long nillnessId : resources.getNillnessIds()) {
            ManipulationNillness nillness = new ManipulationNillness();
            nillness.setIllness(nillnessId);
            nillness.setTpticMnpltId(resources.getId());
            nillness.setStatus(1);
            manipulationNillnessMapper.insert(nillness);
        }
    }

    private void convertCode(TherapeuticManipulation therapeuticManipulation) {
        therapeuticManipulation.setMnNameCode(IntermediateCodeUtils.mn2Code(therapeuticManipulation.getMnName()).replaceAll("-", " -"));
        therapeuticManipulation.setMnTherapyCode(IntermediateCodeUtils.mn2Code(therapeuticManipulation.getMnTherapy()).replaceAll("-", " -"));
        therapeuticManipulation.setMnExplainCode(IntermediateCodeUtils.mn2Code(therapeuticManipulation.getMnExplain()).replaceAll("-", " -"));
        therapeuticManipulation.setMnAttentionCode(IntermediateCodeUtils.mn2Code(therapeuticManipulation.getMnAttention()).replaceAll("-", " -"));
        therapeuticManipulation.setMnUtilityCode(IntermediateCodeUtils.mn2Code(therapeuticManipulation.getMnUtility()).replaceAll("-", " -"));
    }

    private void acquire(List<TherapeuticManipulation> therapeuticManipulations) {
        for (TherapeuticManipulation therapeuticManipulation : therapeuticManipulations) {
            LambdaQueryWrapper<ManipulationIllness> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ManipulationIllness::getTpticMnpltId, therapeuticManipulation.getId()).eq(ManipulationIllness::getStatus, 1);
            List<Long> list = manipulationIllnessMapper.selectList(wrapper).stream().map(ManipulationIllness::getIllnessId).collect(Collectors.toList());
            if (list != null) therapeuticManipulation.setIllnessIds(list);
            LambdaQueryWrapper<ManipulationNillness> wrapper1 = new LambdaQueryWrapper<>();
            wrapper1.eq(ManipulationNillness::getTpticMnpltId, therapeuticManipulation.getId()).eq(ManipulationNillness::getStatus, 1);
            List<Long> list1 = manipulationNillnessMapper.selectList(wrapper1).stream().map(ManipulationNillness::getIllness).collect(Collectors.toList());
            if (list1 != null) therapeuticManipulation.setNillnessIds(list1);
        }
    }
}
